package com.xiongda.config;

import java.io.IOException;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.TimeZone;

import org.springframework.stereotype.Component;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;

/**
 *
 */
@Component
public class JacksonObjectMapper extends ObjectMapper {
    private static final long serialVersionUID = -624755482354300157L;

    public JacksonObjectMapper() {
        //super.setDateFormat(DATE_FORMAT);
        super.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        super.enable(JsonParser.Feature.ALLOW_SINGLE_QUOTES);
        // 设置输入时忽略JSON字符串中存在而Java对象实际没有的属性
        super.enable(JsonParser.Feature.ALLOW_SINGLE_QUOTES);
        super.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
        // 设置将驼峰命名法转换成下划线的方式输入输出
        super.setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
        super.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
        super.disable(SerializationFeature.WRITE_NULL_MAP_VALUES);
        // 设定是否使用Enum的toString函数来读取Enum, 为False时使用Enum的name()函数来读取Enum,
        super.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING);
        // 如果输入不存在的字段时不会报错
        super.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        // 使用默认的Jsckson注解
        super.setAnnotationIntrospector(new JacksonAnnotationIntrospector());

        this.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
            @Override
            public void serialize(Object value, JsonGenerator gen, SerializerProvider sp) throws IOException {
                Class<?> fieldType = getFieldType(gen.getCurrentValue(), gen.getOutputContext().getCurrentName());
                gen.getOutputContext().getCurrentIndex();
                if (Number.class.isAssignableFrom(fieldType)) {
                    gen.writeNumber(BigDecimal.ZERO);
                } else if (List.class.isAssignableFrom(fieldType)) {
                    gen.writeObject(new ArrayList<>());
                } else if (String.class.isAssignableFrom(fieldType)) {
                    gen.writeString("");
                } else {
                    gen.writeObject(value);
                }

            }
        });
    }

    /**
     * 获取字段类型
     *
     * @param object
     * @param key
     * @return
     */
    public static Class<?> getFieldType(Object object, String key) {
        String[] arr = key.split("_");
        StringBuffer stringBuffer = new StringBuffer();
        for (int i = 0; i < arr.length; i++) {
            String str = arr[i];
            if (i == 0) {
                stringBuffer.append(str);
            } else {
                stringBuffer.append(str.substring(0, 1).toUpperCase());
                stringBuffer.append(str.substring(1));
            }
        }
        key = stringBuffer.toString();

        Class<?> clz = object.getClass();
        // 获取实体类的所有属性，返回Field数组  
        Field[] fields = clz.getDeclaredFields();
        for (Field field : fields) {
            if (field.getName().equals(key)) {
                return field.getType();
            }
        }
        return String.class;
    }


}